package iotwisp.school.user.service;

import iotwisp.base.cqrs.BusinessException;
import iotwisp.base.orm.BaseDao;
import iotwisp.base.tree.EMTreeData;
import iotwisp.school.user.command.organization.CreateOrganizationSCmd;
import iotwisp.school.user.command.organization.ModifyOrganizationSCmd;
import iotwisp.school.user.command.organization.RemoveOrganizationSCmd;
import iotwisp.school.user.entity.Organization;
import iotwisp.school.user.entity.Role;
import iotwisp.school.user.qo.OrganizationQO;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class OrganizationService extends BaseDao<Organization, OrganizationQO> {

    @Autowired
    private RoleService roleService;

    public Organization createOrganization(CreateOrganizationSCmd cmd) {

        Organization parentOrganization = get(cmd.getParentOrganizationId());

        if (StringUtils.isBlank(cmd.getDefaultRoleId())) {
            cmd.setDefaultRoleId("org_default_role");
        }
        Role defaultRole = roleService.get(cmd.getDefaultRoleId());

        Organization organization = new Organization();
        EMTreeData emTreeData = addTreeNode("org", parentOrganization.getId(), null, "Organization", null, "remove");
        organization.create(cmd, parentOrganization, defaultRole);
        organization.setTreeData(emTreeData);

        save(organization);

        return organization;
    }

    @Transactional(rollbackFor = BusinessException.class)
    public Organization modifyOrganization(ModifyOrganizationSCmd cmd) throws BusinessException {

        if (StringUtils.isBlank(cmd.getDefaultRoleId())) {
            cmd.setDefaultRoleId("org_default_role");
        }

        Role defaultRole = roleService.get(cmd.getDefaultRoleId());

        OrganizationQO organizationQO = new OrganizationQO();
        organizationQO.setId(cmd.getOrganizationId());
        organizationQO.setFetchManageLimit(true);
        Organization organization = queryUnique(organizationQO);

        if (organization == null) {
            throw BusinessException.getInstance(BusinessException.ENTITY_NOT_FOUND, "机构不存在");
        }
        //  查出上级机构
        Organization parentOrganization = null;
        if (StringUtils.isNotBlank(cmd.getParentOrganizationId())) {

            OrganizationQO parentOrganizationQO = new OrganizationQO();
            parentOrganizationQO.setId(cmd.getParentOrganizationId());
            parentOrganization = queryUnique(parentOrganizationQO);

            if (parentOrganization == null) {
                throw BusinessException.getInstance(BusinessException.ENTITY_NOT_FOUND, "上级机构不存在");
            }

            //  如果上级机构变了，移动节点
            if (!StringUtils.equals(organization.getTreeData().getParentId(), cmd.getParentOrganizationId())) {
                moveTreeNode(organization, parentOrganization, null, "Organization", "remove");
            }
        }

        //  修改上级机构
        getSession().evict(organization);
        organization = queryUnique(organizationQO);

        organization.modify(cmd, parentOrganization, defaultRole);
        update(organization);

        return organization;
    }

    public void removeOrganization(RemoveOrganizationSCmd cmd) {

        Organization organization = get(cmd.getOrganiationId());
        organization.remove();
        update(organization);
        removeTreeNode(organization, "Organization", null, "remove");
    }

    @Override
    protected Criteria buildCriteria(Criteria criteria, OrganizationQO qo) {
        return criteria;
    }

    @Override
    protected Class<Organization> getEntityClass() {
        return Organization.class;
    }
}
